﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xunit;
using Moq;

namespace MvcWiki.Test.Service.WikiNamespaceService
{
    public class GetAllWikiNamespacesFacts
    {
        [Fact]
        public void Call()
        {
            var wikiNamespaceRepository = new Mock<MvcWiki.Repository.IWikiNamespaceRepository>();

            var repositoryFactory = new Mock<MvcWiki.Repository.IWikiRepositoryFactory>();
            repositoryFactory.Setup(x => x.GetWikiNamespaceRepository()).Returns(wikiNamespaceRepository.Object);

            var unitOfWork = new Mock<MvcWiki.Repository.IUnitOfWork>();

            var wikiUserProvider = new Mock<MvcWiki.User.IWikiUserProvider>();
            wikiUserProvider.Setup(x => x.CanIndexNamespaces()).Returns(true);

            var service = new MvcWiki.Service.WikiNamespaceService(repositoryFactory.Object, unitOfWork.Object, wikiUserProvider.Object);

            IList<MvcWiki.Model.WikiNamespace> wikiNamespaces = service.GetAllWikiNamespaces();
        }

        [Fact]
        public void Calls_Repository()
        {
            var wikiNamespaceRepository = new Mock<MvcWiki.Repository.IWikiNamespaceRepository>();
            wikiNamespaceRepository.Setup(x => x.GetAllWikiNamespaces());

            var repositoryFactory = new Mock<MvcWiki.Repository.IWikiRepositoryFactory>();
            repositoryFactory.Setup(x => x.GetWikiNamespaceRepository()).Returns(wikiNamespaceRepository.Object);

            var unitOfWork = new Mock<MvcWiki.Repository.IUnitOfWork>();

            var wikiUserProvider = new Mock<MvcWiki.User.IWikiUserProvider>();
            wikiUserProvider.Setup(x => x.CanIndexNamespaces()).Returns(true);

            var service = new MvcWiki.Service.WikiNamespaceService(repositoryFactory.Object, unitOfWork.Object, wikiUserProvider.Object);

            service.GetAllWikiNamespaces();

            wikiNamespaceRepository.VerifyAll();
        }

        [Fact]
        public void Returns_IList_Of_WikiNamespaces()
        {
            var wikiNamespaces = new List<MvcWiki.Model.WikiNamespace> {
                new MvcWiki.Model.WikiNamespace(),
                new MvcWiki.Model.WikiNamespace(),
                new MvcWiki.Model.WikiNamespace()
            };

            var wikiNamespaceRepository = new Mock<MvcWiki.Repository.IWikiNamespaceRepository>();
            wikiNamespaceRepository.Setup(x => x.GetAllWikiNamespaces()).Returns(wikiNamespaces);

            var repositoryFactory = new Mock<MvcWiki.Repository.IWikiRepositoryFactory>();
            repositoryFactory.Setup(x => x.GetWikiNamespaceRepository()).Returns(wikiNamespaceRepository.Object);

            var unitOfWork = new Mock<MvcWiki.Repository.IUnitOfWork>();

            var wikiUserProvider = new Mock<MvcWiki.User.IWikiUserProvider>();
            wikiUserProvider.Setup(x => x.CanIndexNamespaces()).Returns(true);

            var service = new MvcWiki.Service.WikiNamespaceService(repositoryFactory.Object, unitOfWork.Object, wikiUserProvider.Object);

            Assert.Equal<IList<MvcWiki.Model.WikiNamespace>>(wikiNamespaces, service.GetAllWikiNamespaces());
        }

        [Fact]
        public void Calls_WikiUserProvider_CanIndexNamespaces()
        {
            var wikiNamespaceRepository = new Mock<MvcWiki.Repository.IWikiNamespaceRepository>();
            wikiNamespaceRepository.Setup(x => x.GetAllWikiNamespaces());

            var repositoryFactory = new Mock<MvcWiki.Repository.IWikiRepositoryFactory>();
            repositoryFactory.Setup(x => x.GetWikiNamespaceRepository()).Returns(wikiNamespaceRepository.Object);

            var unitOfWork = new Mock<MvcWiki.Repository.IUnitOfWork>();

            var wikiUserProvider = new Mock<MvcWiki.User.IWikiUserProvider>();
            wikiUserProvider.Setup(x => x.CanIndexNamespaces()).Returns(true);

            var service = new MvcWiki.Service.WikiNamespaceService(repositoryFactory.Object, unitOfWork.Object, wikiUserProvider.Object);

            service.GetAllWikiNamespaces();

            wikiUserProvider.Verify(x => x.CanIndexNamespaces());
        }

        [Fact]
        public void Throws_Exception_If_CanIndexNamespaces_Is_False()
        {
            var wikiNamespaceRepository = new Mock<MvcWiki.Repository.IWikiNamespaceRepository>();
            wikiNamespaceRepository.Setup(x => x.GetAllWikiNamespaces());

            var repositoryFactory = new Mock<MvcWiki.Repository.IWikiRepositoryFactory>();
            repositoryFactory.Setup(x => x.GetWikiNamespaceRepository()).Returns(wikiNamespaceRepository.Object);

            var unitOfWork = new Mock<MvcWiki.Repository.IUnitOfWork>();

            var wikiUserProvider = new Mock<MvcWiki.User.IWikiUserProvider>();
            wikiUserProvider.Setup(x => x.CanIndexNamespaces()).Returns(false);

            var service = new MvcWiki.Service.WikiNamespaceService(repositoryFactory.Object, unitOfWork.Object, wikiUserProvider.Object);

            Assert.Throws<MvcWiki.Exceptions.AuthorizationException>(
                () => service.GetAllWikiNamespaces());
        }
    }
}